<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>读书工作台</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }

        body {
            background-color: #f5f7fa;
            color: #333;
            line-height: 1.6;
        }

        .container {
            display: flex;
            min-height: 100vh;
            max-width: 1600px;
            margin: 0 auto;
            box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
            background-color: white;
        }

        /* 左侧边栏样式 */
        .sidebar {
            width: 320px;
            background: linear-gradient(135deg, #2c3e50, #4a6491);
            color: white;
            padding: 25px 15px;
            overflow-y: auto;
            scrollbar-width: none;
            /* Firefox */
            -ms-overflow-style: none;
            /* IE and Edge */
        }

        /* 悬停时显示滚动条 */
        .sidebar:hover::-webkit-scrollbar-thumb {
            background-color: rgba(0, 0, 0, 0.5);
        }

        .sidebar:hover {
            scrollbar-width: thin;
            /* Firefox */
        }

        .logo {
            text-align: center;
            margin-bottom: 30px;
            padding-bottom: 20px;
            border-bottom: 1px solid rgba(255, 255, 255, 0.2);
        }

        .logo h1 {
            font-size: 1.5rem;
            font-weight: 600;
        }

        .list-group {
            margin-bottom: 30px;
        }

        .list-title {
            font-size: 1.1rem;
            margin-bottom: 15px;
            padding-left: 10px;
            border-left: 3px solid #3498db;
        }

        .list {
            list-style: none;
            background-color: rgba(255, 255, 255, 0.1);
            border-radius: 8px;
            overflow: auto;
            max-height: 480px;
            scrollbar-width: none;
            /* Firefox */
            -ms-overflow-style: none;
            /* IE and Edge */
        }

        .list::-webkit-scrollbar-thumb {
            background-color: transparent;
            border-radius: 4px;
        }

        /* 悬停时显示滚动条 */
        .list:hover::-webkit-scrollbar-thumb {
            background-color: rgba(0, 0, 0, 0.5);
        }

        .list:hover {
            scrollbar-width: thin;
            /* Firefox */
        }

        .list-item {
            padding: 3px 6px;
            border-bottom: 1px solid rgba(255, 255, 255, 0.1);
            cursor: pointer;
            transition: all 0.3s ease;
        }

        .list-item:hover {
            background-color: rgba(255, 255, 255, 0.15);
            padding-left: 20px;
        }

        .list-item:last-child {
            border-bottom: none;
        }

        .list-item.active {
            background-color: rgba(52, 152, 219, 0.3);
            border-left: 3px solid #3498db;
        }

        /* 中间Canvas区域样式 */
        .main-content {
            flex: 1;
            padding: 25px;
            display: flex;
            flex-direction: column;
            background-color: #f9fafb;
            overflow: auto;
            scrollbar-width: none;
            /* Firefox */
            -ms-overflow-style: none;
            /* IE and Edge */
        }

        /* 悬停时显示滚动条 */
        .main-content:hover::-webkit-scrollbar-thumb {
            background-color: rgba(0, 0, 0, 0.5);
        }

        .main-content:hover {
            scrollbar-width: thin;
            /* Firefox */
        }

        .canvas-container {
            flex: 1;
            background-color: white;
            border-radius: 10px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
            overflow: auto;
            display: flex;
            flex-direction: column;
            scrollbar-width: none;
            /* Firefox */
            -ms-overflow-style: none;
            /* IE and Edge */
        }

        /* 悬停时显示滚动条 */
        .canvas-container:hover::-webkit-scrollbar-thumb {
            background-color: rgba(0, 0, 0, 0.5);
        }

        .canvas-container:hover {
            scrollbar-width: thin;
            /* Firefox */
        }

        .canvas-header {
            padding: 15px 20px;
            background-color: #3498db;
            color: white;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .canvas-header h2 {
            font-size: 1.3rem;
            font-weight: 500;
        }

        .canvas-controls {
            display: flex;
            gap: 5px;
        }

        .canvas-controls button {
            background-color: rgba(255, 255, 255, 0.2);
            border: none;
            color: white;
            padding: 6px 12px;
            border-radius: 4px;
            cursor: pointer;
            transition: background-color 0.3s;
        }

        .canvas-controls input {
            background-color: rgba(255, 255, 255, 0.2);
            border: none;
            color: white;
            padding: 6px 12px;
            border-radius: 4px;
            cursor: pointer;
            transition: background-color 0.3s;
        }

        .canvas-controls button:hover {
            background-color: rgba(255, 255, 255, 0.3);
        }

        canvas {
            flex: 1;
            background-color: white;
            cursor: crosshair;
        }

        /* 右侧边栏样式 */
        .right-sidebar {
            width: 320px;
            padding: 25px 20px;
            background-color: white;
            overflow-y: auto;
            border-left: 1px solid #eaeaea;
            scrollbar-width: none;
            /* Firefox */
            -ms-overflow-style: none;
            /* IE and Edge */
        }

        /* 悬停时显示滚动条 */
        .right-sidebar::-webkit-scrollbar-thumb {
            background-color: rgba(0, 0, 0, 0.5);
        }

        .right-sidebar:hover {
            scrollbar-width: thin;
            /* Firefox */
        }

        .info-section {
            margin-bottom: 30px;
        }

        .info-section h3 {
            font-size: 1.2rem;
            margin-bottom: 15px;
            color: #2c3e50;
            padding-bottom: 8px;
            border-bottom: 2px solid #3498db;
        }

        .info-content {
            background-color: #f8f9fa;
            padding: 5px;
            border-radius: 8px;
            border-left: 4px solid #3498db;
        }

        .info-content p {
            margin-bottom: 0px;
        }

        .info-content p:last-child {
            margin-bottom: 0;
        }

        .info-content canvas {
            width: 100%;
            height: 100%;
            margin: 0px;
        }

        .info-content input {
            width: 100%;
            margin: 0px;
        }

        .info-content select {
            width: 100%;
            margin-top: 5px;
        }

        .info-content textarea {
            width: 100%;
            min-height: 100px;
            max-height: 500px;
            margin-top: 5px;
            padding: 5px;
            font-size: 1rem;
            border: 1px solid #ced4da;
            border-radius: 4px;
            outline: none;
            transition: border-color 0.3s;
            resize: vertical;
        }

        .info-content button {
            border: none;
            color: black;
            padding: 6px 12px;
            border-radius: 4px;
            cursor: pointer;
            transition: background-color 0.3s;
        }

        .stats {
            display: flex;
            justify-content: space-between;
            margin-top: 15px;
        }

        .stat-item {
            text-align: center;
            padding: 10px;
            background-color: #3498db;
            color: white;
            border-radius: 6px;
            flex: 1;
            margin: 0 5px;
        }

        .stat-value {
            font-size: 1.5rem;
            font-weight: bold;
        }

        .stat-input {
            font-size: 1.5rem;
            font-weight: bold;
            color: white;
            background-color: #3498db;
            border: none;
            width: 100%;
        }

        .stat-label {
            font-size: 0.8rem;
            opacity: 0.9;
        }

        /* 响应式设计 */
        @media (max-width: 1024px) {
            .container {
                flex-direction: column;
            }

            .sidebar,
            .right-sidebar {
                width: 100%;
            }

            .sidebar {
                order: 1;
            }

            .main-content {
                order: 2;
                min-height: 500px;
            }

            .right-sidebar {
                order: 3;
            }
        }
    </style>
</head>

<body>
    <div class="container">
        <!-- 左侧边栏 -->
        <div id="sidebar" class="sidebar">
            <div class="logo">
                <h1>读书工作台</h1>
            </div>

            <div class="list-group">
                <h3 class="list-title">图书筛选</h3>
                <ul class="list">
                    <li class="list-item" active>
                        <label for="category">分类筛选:</label>
                        <select id="category" class="list-item">
                            <option value="all" selected>所有分类</option>
                            <option value="电子产品">电子产品</option>
                            <option value="服装">服装</option>
                            <option value="图书">图书</option>
                            <option value="家居用品">家居用品</option>
                        </select>
                    </li>
                    <li class="list-item">
                        <label for="pdf-name">名称筛选:</label>
                        <input type="text" id="pdf-name" placeholder="名称包含">
                    </li>
                    <li class="list-item" id="apply-filter">应用筛选</li>
                    <li class="list-item" id="reset-filter">重置</li>
                    <li class="list-item">
                        <label for="sort-by">排序方式:</label>
                        <select id="sort-by" class="list-item">
                            <option value="name-asc">名称 (A-Z)</option>
                            <option value="name-desc">名称 (Z-A)</option>
                        </select>
                    </li>
                    <li class="list-item">
                        <label for="sort-by">当前浏览:</label>
                        <input type="number" id="current-page">
                    </li>
                </ul>
            </div>

            <div class="list-group">
                <h3 class="list-title">图书目录</h3>
                <ul class="list" id="product-list"></ul>
            </div>
            <script>
                document.getElementById('current-page').addEventListener("change", function (event) {
                    localStorage.setItem(localStorage.getItem("path_to_pdf"), event.target.value)
                    IC.get_pdf_page();
                });
                // 产品数据
                const products = [
                    { id: 1, name: "智能手机", category: "电子产品", price: 2999, rating: 4.5 },
                    { id: 2, name: "笔记本电脑", category: "电子产品", price: 5999, rating: 4.7 },
                    { id: 3, name: "无线耳机", category: "电子产品", price: 399, rating: 4.2 },
                    { id: 4, name: "智能手表", category: "电子产品", price: 1299, rating: 4.3 },
                    { id: 5, name: "T恤", category: "服装", price: 99, rating: 4.0 },
                    { id: 6, name: "牛仔裤", category: "服装", price: 199, rating: 4.1 },
                    { id: 7, name: "运动鞋", category: "服装", price: 299, rating: 4.4 },
                    { id: 8, name: "夹克", category: "服装", price: 399, rating: 4.2 },
                    { id: 9, name: "JavaScript高级程序设计", category: "图书", price: 89, rating: 4.8 },
                    { id: 10, name: "设计模式", category: "图书", price: 75, rating: 4.6 },
                    { id: 11, name: "咖啡杯", category: "家居用品", price: 45, rating: 3.9 },
                    { id: 12, name: "台灯", category: "家居用品", price: 129, rating: 4.0 },
                    { id: 13, name: "枕头", category: "家居用品", price: 89, rating: 4.3 },
                    { id: 14, name: "空气净化器", category: "家居用品", price: 899, rating: 4.5 }
                ];

                class ListShow {
                    constructor() {
                        this.productList = document.getElementById('product-list');
                        this.categoryFilter = document.getElementById('category');
                        this.pdfName = document.getElementById('pdf-name');
                        this.applyFilterBtn = document.getElementById('apply-filter');
                        this.resetFilterBtn = document.getElementById('reset-filter');
                        this.sortBySelect = document.getElementById('sort-by');
                        this.currentFilters = { category: 'all', minPrice: null, maxPrice: null, pdfName: null };
                        this.url = "/get_pdfs";
                        this.products = null;
                        this.get_pdfs();
                    }
                    init() {
                        this.renderProducts(this.products);
                        this.applyFilterListener(this.applyFilterBtn, this);
                        this.resetFilterListener(this.resetFilterBtn, this);
                        this.sortBySelectListener(this.sortBySelect, this);
                    }
                    async get_pdfs() {
                        try {
                            const response = await fetch(this.url);
                            const data = await response.json();
                            localStorage.setItem("pdf_files", JSON.stringify(data.pdf_files));
                            const pdf_files = JSON.parse(localStorage.getItem("pdf_files"));
                            const categoryFilter = document.getElementById('category');
                            categoryFilter.innerHTML = '<option value="all" selected>所有分类</option>';
                            this.products = []
                            let categorys = [];
                            let books = 0, browse_count = 0;
                            for (let category in pdf_files) {
                                books += Object.keys(pdf_files[category]).length;
                                categorys.includes(category) || categorys.push(category);
                                for (let pdfName in pdf_files[category]) {
                                    if (localStorage.getItem(`${category}\\${pdfName}`)) {
                                        browse_count++;
                                    }
                                    this.products.push({ name: pdfName, category: category, pages: pdf_files[category][pdfName] })
                                }
                            }
                            document.getElementById('books-count').textContent = books;
                            document.getElementById('browse-count').textContent = browse_count;
                            categorys.forEach(item => {
                                const option = document.createElement("option");
                                option.value = item;
                                option.textContent = item;
                                categoryFilter.append(option);
                            });
                            this.init();
                            IC.get_pdf_page();
                        } catch (error) {
                            alert('识别失败: ' + error.message);
                        }
                    }
                    applyFilterListener(element, someVariable) {
                        element.addEventListener('click', function () {
                            someVariable.applyFilters();
                        });
                    }
                    resetFilterListener(element, someVariable) {
                        element.addEventListener('click', function () {
                            someVariable.resetFilters();
                        });
                    }
                    sortBySelectListener(element, someVariable) {
                        element.addEventListener('change', function () {
                            someVariable.handleSortChange();
                        });
                    }
                    renderProducts(productsToRender) {
                        this.productList.innerHTML = '';
                        if (productsToRender.length === 0) {
                            this.productList.innerHTML = '<li class="list-item">没有找到符合条件的产品</li>';
                            return;
                        }
                        productsToRender.forEach(product => {
                            const li = document.createElement('li');
                            li.className = 'list-item';
                            li.innerHTML = `${product.name}, ${product.category}, ${product.pages}`;
                            li.addEventListener("click", function (event) {
                                let filename = `${product.category}\\${product.name}`;
                                localStorage.setItem("path_to_pdf", filename);
                                let page_num = localStorage.getItem(filename) || 1;
                                localStorage.setItem(filename, page_num);
                                IC.get_pdf_page();
                            })
                            this.productList.appendChild(li);
                        });
                    }
                    applyFilters() {
                        this.currentFilters.category = this.categoryFilter.value;
                        this.currentFilters.pdfName = this.pdfName.value;
                        this.filterAndSortProducts();
                    }
                    resetFilters() {
                        this.categoryFilter.value = 'all';
                        this.pdfName.value = '';
                        this.currentFilters = { category: 'all', pdfName: null };
                        this.filterAndSortProducts();
                    }
                    handleSortChange() {
                        this.filterAndSortProducts();
                    }
                    filterAndSortProducts() {
                        let filteredProducts = [...this.products];
                        const pdf_files = JSON.parse(localStorage.getItem("pdf_files"));
                        if (pdf_files.hasOwnProperty(this.currentFilters.category)) {
                            filteredProducts = filteredProducts.filter(p => p.category === this.currentFilters.category);
                        }
                        if (this.currentFilters.pdfName !== null) {
                            filteredProducts = filteredProducts.filter(p => p.name.includes(this.currentFilters.pdfName));
                        }
                        const sortValue = this.sortBySelect.value;
                        switch (sortValue) {
                            case 'name-asc':
                                filteredProducts.sort((a, b) => a.name.localeCompare(b.name));
                                break;
                            case 'name-desc':
                                filteredProducts.sort((a, b) => b.name.localeCompare(a.name));
                                break;
                            case 'price-asc':
                                filteredProducts.sort((a, b) => a.price - b.price);
                                break;
                            case 'price-desc':
                                filteredProducts.sort((a, b) => b.price - a.price);
                                break;
                            case 'rating-desc':
                                filteredProducts.sort((a, b) => b.rating - a.rating);
                                break;
                            default:
                                break;
                        }
                        this.renderProducts(filteredProducts);
                    }
                }
                const LS = new ListShow();

            </script>

        </div>

        <!-- 中间主内容区 -->
        <div id="main-content" class="main-content">
            <div class="canvas-container">
                <div class="canvas-header">
                    <h2>画布区域</h2>
                    <div class="canvas-controls">
                        <input type="file" id="imageInput" accept="image/*">
                        <button id="saveBtn">保存</button>
                        <button id="zoomInBtn">放大</button>
                        <button id="zoomOutBtn">缩小</button>
                        <button id="resetBtn">复位</button>
                        <button id="selectionModeBtn">框选模式</button>
                        <button id="home-page">首页</button>
                        <button id="front-flip">前</button>
                        <button id="flip-back">后</button>
                    </div>
                </div>
                <canvas id="mainCanvas"></canvas>
            </div>
        </div>

        <!-- 右侧边栏 -->
        <div id="right-sidebar" class="right-sidebar">
            <div class="info-section">
                <h3>项目统计</h3>
                <div class="stats">
                    <div class="stat-item">
                        <div id="books-count" class="stat-value">9999</div>
                        <div class="stat-label">书本量</div>
                    </div>
                    <div class="stat-item">
                        <div id="browse-count" class="stat-value">555</div>
                        <div class="stat-label">浏览数</div>
                    </div>
                </div>
            </div>

            <div class="info-section">
                <h3>框选区域 信息</h3>
                <div class="info-content">
                    <div class="editable-item" data-id="1">
                        <strong>当前缩放：</strong>
                        <span class="editable-content" id="scaleValue">1.00</span>
                    </div>
                    <div class="editable-item" data-id="2">
                        <strong>当前位置：</strong>
                        <strong> X：</strong>
                        <span class="editable-content" id="posX">0</span>
                        <strong> Y：</strong>
                        <span class="editable-content" id="posY">0</span>
                    </div>
                    <div class="editable-item" data-id="3">
                        <strong>框选状态：</strong>
                        <span class="editable-content" id="selectionStatus">未选择</span>
                    </div>
                    <div class="editable-item" data-id="4">
                        <strong>框选区域：</strong>
                        <span class="editable-content" id="selectionArea">0x0</span>
                    </div>
                </div>
                <div class="info-content">
                    <canvas id="previewCanvas"></canvas>
                </div>
            </div>

            <div class="info-section">
                <h3>OCR AI</h3>
                <div class="info-content">
                    <input type="url" id="" class="list-item" placeholder="ollama url" />
                    <select id="" class="list-item">
                        <option value="all" selected>所有分类</option>
                        <option value="电子产品">电子产品</option>
                        <option value="服装">服装</option>
                        <option value="图书">图书</option>
                        <option value="家居用品">家居用品</option>
                    </select>
                    <textarea id="system-prompt" class="list-item" placeholder="系统提示词"></textarea>
                    <button id="" class="list-item" onclick="uploadImage()">OCR</button>
                    <button id="" class="list-item">Ollama</button>
                    <textarea id="user-prompt" class="list-item"></textarea>
                    <pre id="" class="list-item">ai</pre>
                </div>
            </div>

            <div class="info-section">
                <h3>使用说明</h3>
                <div class="info-content">
                    <p>上传图片：点击"选择文件"按钮上传图片</p>
                    <p>平移图片：在画布上按住鼠标左键并拖动</p>
                    <p>缩放图片：使用放大/缩小按钮或鼠标滚轮</p>
                    <p>框选区域：点击"框选模式"按钮，然后在画布上拖动鼠标选择区域</p>
                    <p>复位：点击"复位"按钮恢复初始状态</p>
                </div>
            </div>

            <div class="info-section">
                <h3>操作信息</h3>
                <div id="info-content" class="info-content">
                    <div class="editable-item">
                        <strong>书名（Title）：</strong>
                        <span class="editable-content" id="">图书的正式名称，可能包含副标题。</span>
                    </div>
                    <div class="editable-item">
                        <strong>作者（Author）：</strong>
                        <span class="editable-content" id="">主要作者姓名，可能包括合著者、编者或译者。</span>
                    </div>
                    <div class="editable-item">
                        <strong>出版社（Publisher）：</strong>
                        <span class="editable-content" id="">出版机构的名称及所在地。</span>
                    </div>
                    <div class="editable-item">
                        <strong>出版日期（Publication Date）：</strong>
                        <span class="editable-content" id="">首次出版年份或具体日期，可能标注版本（如第2版）。</span>
                    </div>
                    <div class="editable-item">
                        <strong>ISBN（国际标准书号）：</strong>
                        <span class="editable-content" id="">图书的唯一标识码，用于区分不同版本或装帧形式（如精装/平装）。</span>
                    </div>
                </div>
            </div>
            <script>
                class EditableContentManager {
                    constructor() {
                        this.container = document.getElementById('info-content');
                        this.editableItems = [];
                        this.init();
                    }

                    init() {
                        this.setupEditableItems();
                    }

                    setupEditableItems() {
                        this.editableItems = Array.from(this.container.querySelectorAll('.editable-item'));
                        //this.editableItems = Array.from(document.querySelectorAll('.editable-item'));
                        this.editableItems.forEach(item => {
                            item.addEventListener('dblclick', () => {
                                this.startEditing(item);
                            });
                        });
                    }

                    startEditing(item) {
                        if (item.classList.contains('editing')) return;

                        const contentElement = item.querySelector('.editable-content');
                        const currentValue = contentElement.textContent;

                        const input = document.createElement('input');
                        input.type = 'text';
                        input.className = 'editable-input';
                        input.value = currentValue;

                        contentElement.style.display = 'none';
                        item.appendChild(input);
                        item.classList.add('editing');
                        input.focus();
                        input.select();

                        const saveEdit = () => {
                            const newValue = input.value.trim();
                            contentElement.textContent = newValue || currentValue;
                            contentElement.style.display = 'inline';
                            item.removeChild(input);
                            item.classList.remove('editing');

                            input.removeEventListener('blur', saveEdit);
                            input.removeEventListener('keydown', handleKeyDown);

                            this.logAllEditableContents();
                        };

                        const cancelEdit = () => {
                            contentElement.style.display = 'inline';
                            item.removeChild(input);
                            item.classList.remove('editing');

                            input.removeEventListener('blur', saveEdit);
                            input.removeEventListener('keydown', handleKeyDown);
                        };

                        const handleKeyDown = (e) => {
                            if (e.key === 'Enter') {
                                saveEdit();
                            } else if (e.key === 'Escape') {
                                cancelEdit();
                            }
                        };

                        input.addEventListener('blur', saveEdit);
                        input.addEventListener('keydown', handleKeyDown);
                    }

                    logAllEditableContents() {
                        const editableContents = this.container.querySelectorAll('.editable-content');
                        const items = Array.from(editableContents).map(item => item.textContent);
                    }

                    // 可选：添加公共方法来刷新可编辑项
                    refreshEditableItems() {
                        this.setupEditableItems();
                    }
                }
                // 使用示例
                const editableManager = new EditableContentManager();
            </script>

        </div>
    </div>

    <script>

        class ImageCanvas {
            constructor() {
                this.mainCanvas = document.getElementById('mainCanvas'); // 获取DOM元素
                this.ctx = mainCanvas.getContext('2d');
                this.previewCanvas = document.getElementById('previewCanvas');
                this.previewCtx = previewCanvas.getContext('2d');
                this.imageInput = document.getElementById('imageInput');
                this.zoomInBtn = document.getElementById('zoomInBtn');
                this.zoomOutBtn = document.getElementById('zoomOutBtn');
                this.resetBtn = document.getElementById('resetBtn');
                this.selectionModeBtn = document.getElementById('selectionModeBtn');
                this.scaleValue = document.getElementById('scaleValue');
                this.posX = document.getElementById('posX');
                this.posY = document.getElementById('posY');
                this.selectionStatus = document.getElementById('selectionStatus');
                this.selectionArea = document.getElementById('selectionArea');
                this.home_page = document.getElementById('home-page');
                this.front_flip = document.getElementById('front-flip');
                this.flip_back = document.getElementById('flip-back');
                this.img = null; // 状态变量
                this.blob = null;
                this.scale = 1;
                this.offsetX = 0;
                this.offsetY = 0;
                this.isDragging = false;
                this.lastX = null;
                this.lastY = null;
                this.isSelecting = false;
                this.selectionStartX = null;
                this.selectionStartY = null;
                this.selectionEndX = null;
                this.selectionEndY = null;
                this.hasSelection = false;
            }
            initCanvasSize() {
                const container = this.mainCanvas.parentElement;
                this.mainCanvas.width = container.clientWidth;
                this.mainCanvas.height = container.clientHeight;
                this.previewCanvas.width = this.previewCanvas.parentElement.clientWidth;
                this.previewCanvas.height = 200;
                this.elementListener(this);
                document.getElementById('sidebar').style.height = `${window.innerHeight}px`;
                document.getElementById('main-content').style.height = `${window.innerHeight}px`;
                document.getElementById('right-sidebar').style.height = `${window.innerHeight}px`;
            }
            drawMainCanvas() {
                this.ctx.clearRect(0, 0, this.mainCanvas.width, this.mainCanvas.height);
                if (!this.img) return;
                this.ctx.save();
                this.ctx.translate(this.offsetX, this.offsetY);
                this.ctx.scale(this.scale, this.scale);
                this.ctx.drawImage(this.img, 0, 0);
                if (this.isSelecting || this.hasSelection) {
                    const x = Math.min(this.selectionStartX, this.selectionEndX);
                    const y = Math.min(this.selectionStartY, this.selectionEndY);
                    const width = Math.abs(this.selectionEndX - this.selectionStartX);
                    const height = Math.abs(this.selectionEndY - this.selectionStartY);
                    this.ctx.strokeStyle = '#ff0000';
                    this.ctx.lineWidth = 2 / this.scale;
                    this.ctx.setLineDash([5, 5]);
                    this.ctx.strokeRect(x, y, width, height);
                    this.ctx.setLineDash([]);
                }
                this.ctx.restore();
                this.updateInfoPanel();
            }
            drawPreviewCanvas() {
                this.previewCtx.clearRect(0, 0, this.previewCanvas.width, this.previewCanvas.height);
                //if (!this.img || !this.hasSelection) return;
                if (!this.img) return;
                let startX, startY, endX, endY;
                if (this.hasSelection) {
                    startX = this.selectionStartX;
                    startY = this.selectionStartY;
                    endX = this.selectionEndX;
                    endY = this.selectionEndY;
                } else {
                    startX = 0;
                    startY = 0;
                    endX = this.img.width;
                    endY = this.img.height;
                }
                const x = Math.min(startX, endX);
                const y = Math.min(startY, endY);
                const width = Math.abs(endX - startX);
                const height = Math.abs(endY - startY);
                if (width === 0 || height === 0) return;
                const previewRatio = this.previewCanvas.width / this.previewCanvas.height;
                const selectionRatio = width / height;
                let drawWidth, drawHeight;
                if (selectionRatio > previewRatio) {
                    drawWidth = this.previewCanvas.width;
                    drawHeight = this.previewCanvas.width / selectionRatio;
                } else {
                    drawHeight = this.previewCanvas.height;
                    drawWidth = this.previewCanvas.height * selectionRatio;
                }
                const drawX = (this.previewCanvas.width - drawWidth) / 2;
                const drawY = (this.previewCanvas.height - drawHeight) / 2;
                this.previewCtx.drawImage(
                    this.img,
                    x, y, width, height,
                    drawX, drawY, drawWidth, drawHeight
                );
                this.previewCtx.strokeStyle = '#ff0000';
                this.previewCtx.lineWidth = 2;
                this.previewCtx.strokeRect(drawX, drawY, drawWidth, drawHeight);
            }
            updateInfoPanel() {
                this.scaleValue.textContent = this.scale.toFixed(2);
                this.posX.textContent = Math.round(this.offsetX);
                this.posY.textContent = Math.round(this.offsetY);
                if (this.hasSelection) {
                    const width = Math.abs(this.selectionEndX - this.selectionStartX);
                    const height = Math.abs(this.selectionEndY - this.selectionStartY);
                    this.selectionStatus.textContent = '已选择';
                    this.selectionArea.textContent = `${Math.round(width)}x${Math.round(height)}`;
                } else if (this.isSelecting) {
                    this.selectionStatus.textContent = '选择中...';
                    this.selectionArea.textContent = '0x0';
                } else {
                    this.selectionStatus.textContent = '未选择';
                    this.selectionArea.textContent = '0x0';
                }
            }
            elementListener(someVariable) {
                this.imageInput.addEventListener('change', function (e) {
                    const file = e.target.files[0];
                    if (!file) return;
                    const reader = new FileReader();
                    reader.onload = function (event) {
                        someVariable.img = new Image();
                        someVariable.img.onload = function () {
                            someVariable.scale = 1;
                            someVariable.offsetX = 0;
                            someVariable.offsetY = 0;
                            someVariable.hasSelection = false;
                            someVariable.drawMainCanvas();
                        };
                        someVariable.img.src = event.target.result;
                    };
                    reader.readAsDataURL(file);
                });
                this.zoomInBtn.addEventListener('click', function () {
                    someVariable.scale *= 1.2;
                    someVariable.drawMainCanvas();
                });
                this.zoomOutBtn.addEventListener('click', function () {
                    someVariable.scale /= 1.2;
                    someVariable.drawMainCanvas();
                });
                this.resetBtn.addEventListener('click', function () {
                    //someVariable.scale = 1;
                    someVariable.scale = someVariable.mainCanvas.width / someVariable.img.width;
                    someVariable.offsetX = 0;
                    someVariable.offsetY = 0;
                    someVariable.hasSelection = false;
                    someVariable.drawMainCanvas();
                    someVariable.drawPreviewCanvas();
                });
                this.selectionModeBtn.addEventListener('click', function () {
                    someVariable.isSelecting = !someVariable.isSelecting;
                    someVariable.hasSelection = false;
                    someVariable.selectionModeBtn.textContent = someVariable.isSelecting ? '退出框选模式' : '框选模式';
                    someVariable.drawMainCanvas();
                    someVariable.drawPreviewCanvas();
                });
                this.home_page.addEventListener('click', function (e) {
                    localStorage.setItem(localStorage.getItem("path_to_pdf"), 1);
                    someVariable.get_pdf_page();
                });
                this.front_flip.addEventListener('click', function (e) {
                    if (Number(localStorage.getItem(localStorage.getItem("path_to_pdf"))) > 0) {
                        localStorage.setItem(
                            localStorage.getItem("path_to_pdf"),
                            Number(localStorage.getItem(localStorage.getItem("path_to_pdf"))) - 1
                        );
                    }
                    someVariable.get_pdf_page();
                });
                this.flip_back.addEventListener('click', function (e) {
                    localStorage.setItem(
                        localStorage.getItem("path_to_pdf"),
                        Number(localStorage.getItem(localStorage.getItem("path_to_pdf"))) + 1
                    );
                    someVariable.get_pdf_page();
                });
                this.mainCanvas.addEventListener('mousedown', function (e) {
                    if (someVariable.isSelecting) {
                        const rect = someVariable.mainCanvas.getBoundingClientRect();
                        someVariable.selectionStartX = (e.clientX - rect.left - someVariable.offsetX) / someVariable.scale;
                        someVariable.selectionStartY = (e.clientY - rect.top - someVariable.offsetY) / someVariable.scale;
                        someVariable.selectionEndX = someVariable.selectionStartX;
                        someVariable.selectionEndY = someVariable.selectionStartY;
                        someVariable.hasSelection = false;
                    } else {
                        someVariable.isDragging = true;
                        someVariable.lastX = e.clientX;
                        someVariable.lastY = e.clientY;
                        someVariable.mainCanvas.style.cursor = 'grabbing';
                    }
                });
                this.mainCanvas.addEventListener('mousemove', function (e) {
                    if (someVariable.isSelecting && (e.buttons & 1)) {
                        const rect = someVariable.mainCanvas.getBoundingClientRect();
                        someVariable.selectionEndX = (e.clientX - rect.left - someVariable.offsetX) / someVariable.scale;
                        someVariable.selectionEndY = (e.clientY - rect.top - someVariable.offsetY) / someVariable.scale;
                        someVariable.hasSelection = true;
                        someVariable.drawMainCanvas();
                    } else if (someVariable.isDragging) {
                        someVariable.offsetX += e.clientX - someVariable.lastX;
                        someVariable.offsetY += e.clientY - someVariable.lastY;
                        someVariable.lastX = e.clientX;
                        someVariable.lastY = e.clientY;
                        someVariable.drawMainCanvas();
                    }
                });
                this.mainCanvas.addEventListener('mouseup', function (e) {
                    if (someVariable.isSelecting && someVariable.hasSelection) {
                        someVariable.drawPreviewCanvas();
                    }
                    someVariable.isDragging = false;
                    someVariable.mainCanvas.style.cursor = 'grab';
                });
                this.mainCanvas.addEventListener('mouseleave', function () {
                    someVariable.isDragging = false;
                    someVariable.mainCanvas.style.cursor = 'grab';
                });
                this.mainCanvas.addEventListener('wheel', function (e) {
                    e.preventDefault();
                    const rect = someVariable.mainCanvas.getBoundingClientRect();
                    const mouseX = e.clientX - rect.left;
                    const mouseY = e.clientY - rect.top;
                    const zoomFactor = e.deltaY > 0 ? 0.9 : 1.1;
                    const worldX = (mouseX - someVariable.offsetX) / someVariable.scale;
                    const worldY = (mouseY - someVariable.offsetY) / someVariable.scale;
                    someVariable.scale *= zoomFactor;
                    someVariable.offsetX = mouseX - worldX * someVariable.scale;
                    someVariable.offsetY = mouseY - worldY * someVariable.scale;
                    someVariable.drawMainCanvas();
                });
                document.getElementById('saveBtn').addEventListener('click', function () {
                    const link = document.createElement('a');
                    link.download = 'canvas-drawing.png';
                    link.href = someVariable.mainCanvas.toDataURL();
                    link.click();
                });
            }
            async get_pdf_page() {
                const data = {
                    filename: localStorage.getItem("path_to_pdf"),
                    page_number: Number(localStorage.getItem(localStorage.getItem("path_to_pdf"))) || 1
                };
                this.scrollToItem(localStorage.getItem("path_to_pdf"));

                fetch('http://localhost:5000/convert', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify(data)
                })
                    .then(response => {
                        if (!response.ok) {
                            return response.json().then(err => { throw err; });
                        }
                        return response.blob();
                    })
                    .then(blob => {
                        IC.blob = blob;
                        IC.img = new Image();
                        IC.img.onload = function () {
                            // 计算缩放比例和居中位置
                            IC.scale = IC.mainCanvas.width / IC.img.width;
                            IC.mainCanvas.height = IC.img.height * IC.scale;
                            const x = 0, y = 0;
                            // 绘制缩放后的图片
                            IC.ctx.clearRect(0, 0, IC.mainCanvas.width, IC.mainCanvas.height);
                            IC.ctx.drawImage(
                                IC.img,
                                x, y,
                                IC.img.width * IC.scale,
                                IC.img.height * IC.scale
                            );
                            IC.drawPreviewCanvas();
                            document.getElementById('current-page').value = localStorage.getItem(localStorage.getItem("path_to_pdf")) || 1;
                        };
                        IC.img.src = URL.createObjectURL(blob);
                    })
                    .catch(error => {
                        console.error('Error:', error);
                    });
            }
            scrollToItem(searchText) {
                const listItems = document.getElementById('product-list').querySelectorAll('.list-item');
                // 移除之前的高亮
                listItems.forEach(item => item.classList.remove('active'));

                // 查找匹配的列表项
                let found = false;
                const pdfName = searchText.split("\\")[1];
                for (let i = 0; i < listItems.length; i++) {
                    if (listItems[i].textContent.startsWith(pdfName)) {
                        // 滚动到该项
                        listItems[i].scrollIntoView({
                            behavior: 'smooth',
                            block: 'center'
                        });

                        // 高亮显示
                        listItems[i].classList.add('active');

                        //showStatus(`已滚动到: ${searchText}`, "success");
                        found = true;
                        break;
                    }
                }
            }
        }
        const IC = new ImageCanvas();
        // 窗口大小变化时调整Canvas尺寸
        window.addEventListener('resize', function () {
            IC.initCanvasSize();
            IC.drawMainCanvas();
            IC.drawPreviewCanvas();
        });

        // 初始化
        IC.initCanvasSize();
        IC.drawMainCanvas();
        IC.drawPreviewCanvas();

    </script>
    <script>
        // 上传图片到 OCR 接口
        async function uploadImage() {
            if (!IC.blob) {
                alert('请先选择图片！');
                return;
            }

            // 2. 创建 FormData 并上传到 OCR 接口
            const formData = new FormData();
            formData.append('image', IC.blob, 'ocr_image.png'); // 'image' 是后端接收的字段名

            return fetch('http://localhost:5000/ocr', { // OCR 接口地址
                method: 'POST',
                body: formData
                // 注意：不要设置 Content-Type，浏览器会自动处理 multipart/form-data
            })
                .then(ocrResponse => {
                    if (!ocrResponse.ok) {
                        throw new Error(`OCR 请求失败！状态码: ${ocrResponse.status}`);
                    }
                    return ocrResponse.json();
                })
                .then(ocrResult => {
                    const userPrompt = document.getElementById('user-prompt');
                    userPrompt.value = ocrResult.text
                })
                .catch(error => {
                    console.error('Error:', error);
                });
        }
    </script>

</body>

</html>